package com.greet.service.impl;

import com.greet.context.BaseContext;
import com.greet.dto.SetmealDTO;
import com.greet.dto.SetmealPageQueryDTO;
import com.greet.entity.Category;
import com.greet.entity.Dish;
import com.greet.entity.Setmeal;
import com.greet.entity.SetmealDish;
import com.greet.mapper.CategoryMapper;
import com.greet.mapper.DishMapper;
import com.greet.mapper.SetmealDishMapper;
import com.greet.mapper.SetmealMapper;
import com.greet.result.PageResult;
import com.greet.service.SetmealService;
import com.greet.utils.PojoTypeTranformationUtil;
import com.greet.vo.DishItemVO;
import com.greet.vo.SetmealVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private DishMapper dishMapper;


    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        int index = (setmealPageQueryDTO.getPage() - 1) * setmealPageQueryDTO.getPageSize();
        setmealPageQueryDTO.setPage(index);
        List<Setmeal> setmealList = setmealMapper.selectPageQuery(setmealPageQueryDTO);
        PageResult result = new PageResult(setmealMapper.countAll(), setmealList);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertSetmeal(SetmealDTO setmealDTO) {
        //提取setmeal实体
        Setmeal setmeal = PojoTypeTranformationUtil.toSetmeal(setmealDTO);
        setmeal.setUpdateUser(BaseContext.getCurrentId());
        setmeal.setUpdateTime(LocalDateTime.now());
        setmeal.setCreateUser(BaseContext.getCurrentId());
        setmeal.setCreateTime(LocalDateTime.now());
        //写入数据库
        setmealMapper.insert(setmeal);
        //查询生成后的setmeal.id
        List<Setmeal> tmp = setmealMapper.select(
                Setmeal.builder().name(setmeal.getName()).build()
        );
        Long setmealId =  tmp.get(0).getId();

        //删除所有与套餐有关的SetmealDish实体
        setmealDishMapper.deleteBySetmealId(setmealId);
        //提取SetmealDish实体,并插入
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes();
        for (SetmealDish setmealDish: setmealDishList){
            setmealDish.setSetmealId(setmealId);
            setmealDishMapper.insert(setmealDish);
        }
    }

    @Override
    public SetmealVO getById(Long id){
        //查询setmeal实体,并赋值给返回值
        List<Setmeal> setmealList = setmealMapper.select(Setmeal.builder().id(id).build());
        Setmeal setmeal = setmealList.get(0);
        SetmealVO result = PojoTypeTranformationUtil.toSetmealVO(setmeal);
        //查询result.categoryName
        List<Category> categoryList = categoryMapper.select(
                Category.builder().id(setmeal.getCategoryId()).build()
        );
        result.setCategoryName(categoryList.get(0).getName());

        //获取套餐相关菜品列表
        result.setSetmealDishes(setmealDishMapper.selectBySetmealId(setmeal.getId()));
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSetmeal(SetmealDTO setmealDTO) {
        //更新setmeal表
        Setmeal setmeal = PojoTypeTranformationUtil.toSetmeal(setmealDTO);
        setmeal.setUpdateTime(LocalDateTime.now());
        setmeal.setUpdateUser(BaseContext.getCurrentId());
        setmealMapper.update(setmeal);

        //删除套餐关联的SetmealDish实体
        setmealDishMapper.deleteBySetmealId(setmeal.getId());

        //插入前端传过来的SetmealDish实体
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishList){
            setmealDish.setSetmealId(setmeal.getId());
            setmealDishMapper.insert(setmealDish);
        }
    }

    @Override
    public void setStatus(Integer status, Long id) {
        setmealMapper.update(
                Setmeal.builder().id(id).status(status).build()
        );
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByIds(Long[] ids) {
        setmealMapper.deleteByIds(Arrays.stream(ids).toList());
        setmealDishMapper.deleteBySetmealIds(Arrays.stream(ids).toList());
    }

    @Override
    public List<Setmeal> getBycategoryId(Long categoryId) {
        return setmealMapper.select(Setmeal.builder().categoryId(categoryId).build());
    }

    @Override
    public List<DishItemVO> getDishItemVOSById(Long id) {
        List<SetmealDish> setmealDishList = setmealDishMapper.selectBySetmealId(id);
        List<DishItemVO> dishItemVOList = new ArrayList<>(15);
        for (SetmealDish setmealDish : setmealDishList){
            Dish dish = dishMapper.select(
                    Dish.builder().status(1).id(setmealDish.getDishId()).build()
            ).get(0);

            DishItemVO dishItemVO = DishItemVO.builder()
                    .name(dish.getName())
                    .copies(setmealDish.getCopies())
                    .image(dish.getImage())
                    .description(dish.getDescription()).build();

            dishItemVOList.add(dishItemVO);
        }
        return dishItemVOList;
    }

    @Override
    public List<Setmeal> getViewBycategoryId(Long categoryId) {
        return setmealMapper.select(Setmeal.builder().status(1).categoryId(categoryId).build());
    }
}
